#include <stdio.h>
#include <stdint.h>
	
struct bootRegion { //nomenclatura: bxxxxx para los del bpb, exxxx para los de ebpb
	uint8_t		bJumpBoot[3];		//Jump instruction. This instruction will be executed and will skip past the rest of the (non-executable) header if the partition is booted from.
	char 		bOemName[8];		//OEM Name (padded with spaces 0x20). This value determines in which system disk was formatted.
	uint16_t	byteXSector;		//0x0B. Bytes per sector; the most common value is 512. The BIOS Parameter Block starts here.
	uint8_t		bSectXcluster;		//0x0D. Sectors per cluster. Allowed values are powers of two from 1 to 128
	uint16_t	bReserved;			//0x0E. Reserved sector count. The number of sectors before the first FAT in the file system image. At least 1 for this sector, usually 32 for FAT32.
	uint8_t		bNroFat;			//0x10. Number of file allocation tables. Almost always 2;
	uint16_t	bMaxFat16;			//0x11. Maximum number of FAT12 or FAT16 root directory entries. 0 for FAT32, where the root directory is stored in ordinary data clusters.
	uint16_t	bTotalSect;			//0x13. para CantSect <= 65535. x ser FAT32 usamos bTotSect, este va en 0
	uint8_t		bMedia;				//0x15. Media descriptor. Same value of media descriptor should be repeated as first byte of each copy of FAT.
	uint16_t	bSectorXFat16;		//0x16. en 0
	uint16_t	bSectXpista;		//0x18. Sectors per track for disks with geometry,
	uint16_t	bCabezas;			//0x1A. Number of heads for disks with geometry,
	uint32_t	bHiddenSect;		//0x1C. Count of hidden sectors preceding the partition that contains this FAT volume. This field should always be zero on media that are not partitioned.
	uint16_t	bTotSect;			//0x20. para CantSect > 65535
	//exclusivos de FAT32
	uint32_t	eSectXfat;			//0x24. Sectors per file allocation table
	uint16_t	eMirroringFlag;	//0x28. Mirroring flags (4 low bits = active FAT number minus 1, if high bit set)
	uint16_t	eVersion;			//0x2A. va 0
	uint32_t	eNroClustRoot;		//0x2C. Cluster number of root directory start, typically 2 (first cluster) if it contains no bad sector. A partir de aca empieza el sector de datos
	uint16_t	eNroClustFSInfo;	//0x30. Sector number of FS Information Sector, typically 1, i.e., the second of the three FAT32 boot sectors.
	uint16_t	eBKPBoot;			//0x32. First sector number of a copy of the three FAT32 boot sectors, typically 6.
	uint8_t	 	eReserved[12];		//0x34. Reserved (must be 0) - es arreglo de 12 posiciones de uint8_t, que es un byte... mas o menos lo mismo que antes :D
	uint8_t	 	eDriveNum;			//0x40. Physical drive number (0x00 for removable media, 0x80 for hard disks)
	uint8_t	 	eReserved1;			//0x41. Reserved
	uint8_t		extendedBoot;		//0x42. Extended boot signature
	uint32_t 	eVolumeID;			//0x43. Volume ID (serial number)
	char	 	eVolumeLabel[11];	//0x47. Volume Label
	char	 	eTipoFS[8];			//0x52. File system type, padded with blanks (0x20), e.g., "FAT32   "
	char	 	osBootCode[420];	//0x5A. Operating system boot code; does not belong to the Extended BIOS Parameter Block
	char	 	eBootSectSign[2];	//0x1FE. Boot sector signature 0x55 0xAA
} typedef bootRegion;


struct FSRegion {
	char fsInfo[4];			//FS information sector signature (0x52 0x52 0x61 0x41 = "RRaA")
	char fsReserved[480];	//Reserved (byte values are 0x00)
	char fsInfo2[4];		//FS information sector signature (0x72 0x72 0x41 0x61 = "rrAa")
	char fsClustLibres[4];	//Number of free clusters on the drive, or -1 if unknown
	char fsClusJustSeen[4];	//Number of the most recently allocated cluster
	char fsReserved12[12];	//	Reserved (byte values are 0x00)
	char fsInfo3[4];		//FS information sector signature (0x00 0x00 0x55 0xAA)
} typedef FSRegion;



struct FAT32dir { //32 bytes
    char DIR_Name[11];		//Nombre corto del directorio. Se divide en dos partes, una de 8 caracteres para el nombre, y otra de 3 para la extensión.
//    Si DIR_Name[0] = "E5", esta entrada esta libre, es decir, no hay archivo o directorio.
//    Si DIR_Name[0] = "00", esta entrada esta libre (igual que si fuera "E5") y no hay entradas después de esta. Por lo tanto, si estamos recorriendo la estructura del directorio y encontramos esta entrada, no tiene sentido seguir después de este punto.
//    Si DIR_Name[0] = "05", el nombre de este archivo es "E5". Esto es así por que "E5" es un carácter valido en nombres de archivos escritos con caracteres KANJI, y de esta manera se evita que sistemas basados en ese juego de caracteres interpreten la entrada del directorio como vacía.

    char DIR_Attr;			//Atributos específicos del archivo. Los dos bites altos de este byte se deben dejar en 0 y nunca modificarse.
//    ATTR_READ_ONLY ("01"): Significa que el archivo es de solo lectura.
//    ATTR_HIDDEN ("02"): No debe mostrarse este archivo en un listado normal del contenido de ese directorio.
//    ATTR_SYSTEM ("04"): Se trata de un archivo perteneciente al sistema operativo.
//    ATTR_VOLUME_ID ("08"): Debería haber solo un archivo en el volumen con este atributo en 1, y es el directorio raíz. DIR_FstClusHI y DIR_FstClusLO (ver mas abajo) deben ser cero para la etiqueta del volumen.
//    ATTR_DIRECTORY ("10"): Indica que se trata de un directorio y no de un archivo.
//    ATTR_ARCHIVE ("20"): Atributo pensado para las copias de seguridad. Debe ponerse a 1 cuando el software manejador de la FAT crea, renombra o escribe en un archivo. Las utilidades de backup pueden basarse en este bit para realizar sus tareas de respaldo, y ponerlo en 0 para indicar que ya fueron resguardados.
//    ATTR_LONG_NAME: ATTR_READ_ONLY , ATTR_HIDDEN , ATTR_SYSTEM y ATTR_VOLUME_ID en 1. Esta combinación de bits indican que el "archivo" es en realidad parte del nombre largo de otro archivo. Volveremos sobre este tema mas adelante.

    char DIR_NTRes;			//Reservado para Windows NT. Debe ser dejado en cero
    char DIR_CrtTimeTenth;	//Milisegundos de la hora en que se creo el archivo. Este campo en realidad contiene las décimas de segundos. La granularidad de los segundos almacenados en DIR_CrtTime2 es de dos segundos, por lo que este campo puede contener valores entre 0-199 .
    char DIR_CrtTime[2];	//Hora a la que se creo el archivo.
    char DIR_CrtDate[2];	//Fecha en la que se creo el archivo.
    char DIR_LstAcctDate[2];//Fecha en la que se accedió por ultima vez el archivo, ya sea para escribir en el o para leerlo. En el caso de una escritura, este valor debe ser el mismo que el almacenado en DIR_WrtDate. No se guarda la hora del ultimo acceso.
    char DIR_FstClusHI[2];	//Parte alta de la palabra de 32 bits que contiene el primer cluster del archivo.
    char DIR_WrtTime[2];	//Hora de la ultima escritura. La creación del archivo se considera una escritura.
    char DIR_WrtDate[2];	//Fecha de la ultima escritura.
    char DIR_FstClusLO[2];	//Parte baja de la palabra de 32 bits que contiene el primer cluster del archivo.
    char DIR_FileSize[4];	//Tamaño del archivo, en bytes.

} typedef FAT32dir;
